﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.IO;
using System.Net;
using System.Text;

/// <summary>
/// Author: Dan Miller
/// Pulls the ZPid value from Zillow.com's API using the address, 
/// then uses the ZPid to get the Zestimate from the API.
/// </summary>
public class Zestimate
{
    private String ZPropertySearch(String address)
    {
        // used for building zpid
        StringBuilder sb = new StringBuilder();
        // used for query string
        StringBuilder sb2 = new StringBuilder();
        sb2.Append("&address=");

        // build query string
        char[] chArr = new char[150];
        chArr = address.ToCharArray();
        String tempStr;
        int count = 0;
        tempStr = chArr[count].ToString();
        while (tempStr != ",")
        {
            if (tempStr == " ")
            {
                sb2.Append("+");
            }
            else
            {
                sb2.Append(tempStr);
            }
            count++;
            tempStr = chArr[count].ToString();
        }

        sb2.Append("&citystatezip=");

        while (count < address.Length-1)
        {
            count++;
            tempStr = chArr[count].ToString();
            if (tempStr == ",")
            {
                sb2.Append("%2C");
            }
            else if (tempStr == " ")
            {
                sb2.Append("+");
            } else
            {
                sb2.Append(tempStr);
            }
        }
        String qStrAddress = sb2.ToString();
        byte[] buf = new byte[1];
        HttpWebRequest request = (HttpWebRequest)
        WebRequest.Create("http://www.zillow.com/webservice/GetSearchResults.htm?zws-id=X1-ZWz1ctamaszaq3_47pen" + qStrAddress);
        HttpWebResponse response = (HttpWebResponse)
        request.GetResponse();
        Stream resStream = response.GetResponseStream();
        string tempString = "";
        bool foundZPID = false;
        count = 0;

        while (foundZPID == false)
        {
            // get byte for one character
            count = resStream.Read(buf, 0, buf.Length);
            if (count == 0)
            {
                return "0";
            }

            // translate from bytes to ASCII text
            tempString = Encoding.ASCII.GetString(buf, 0, count);
            // find zpid tag
            if (tempString == "z")
            {
                count = resStream.Read(buf, 0, buf.Length);
                tempString = Encoding.ASCII.GetString(buf, 0, count);
                if (tempString == "p")
                {
                    count = resStream.Read(buf, 0, buf.Length);
                    tempString = Encoding.ASCII.GetString(buf, 0, count);
                    if (tempString == "i")
                    {
                        count = resStream.Read(buf, 0, buf.Length);
                        tempString = Encoding.ASCII.GetString(buf, 0, count);
                        if (tempString == "d")
                        {
                            // get rid of extra character
                            count = resStream.Read(buf, 0, buf.Length);
                            count = resStream.Read(buf, 0, buf.Length);
                            tempString = Encoding.ASCII.GetString(buf, 0, count);
                            // build zpid value
                            while (tempString != "<")
                            {
                                sb.Append(tempString);
                                count = resStream.Read(buf, 0, buf.Length);
                                tempString = Encoding.ASCII.GetString(buf, 0, count);
                            }
                            foundZPID = true;
                        }
                    }
                }
            }
        }
        return sb.ToString();
    }


    public String getZestimate(String address)
    {
        // used for building Zestimate value
        StringBuilder sb = new StringBuilder();
        byte[] buf = new byte[1];
        HttpWebRequest request = (HttpWebRequest)
        // get property ZPid from the ZPropertySearch method
            WebRequest.Create("http://www.zillow.com/webservice/GetZestimate.htm?zws-id=X1-ZWz1ctamaszaq3_47pen&zpid=" + ZPropertySearch(address));
        HttpWebResponse response = (HttpWebResponse)
            request.GetResponse();
        Stream resStream = response.GetResponseStream();
        string tempString = null;
        bool foundZestimate = false;
        int count = 0;

        while (foundZestimate == false)
        {
            // get byte for one character
            count = resStream.Read(buf, 0, buf.Length);
            if (count == 0)
            {
                return "n/a";
            }

            // translate from bytes to ASCII text
            tempString = Encoding.ASCII.GetString(buf, 0, count);
            if (tempString == "z")
            {
                count = resStream.Read(buf, 0, buf.Length);
                tempString = Encoding.ASCII.GetString(buf, 0, count);
                if (tempString == "e")
                {
                    count = resStream.Read(buf, 0, buf.Length);
                    tempString = Encoding.ASCII.GetString(buf, 0, count);
                    if (tempString == "s")
                    {
                        count = resStream.Read(buf, 0, buf.Length);
                        tempString = Encoding.ASCII.GetString(buf, 0, count);
                        if (tempString == "t")
                        {
                            count = resStream.Read(buf, 0, buf.Length);
                            tempString = Encoding.ASCII.GetString(buf, 0, count);
                            if (tempString == "i")
                            {
                                count = resStream.Read(buf, 0, buf.Length);
                                tempString = Encoding.ASCII.GetString(buf, 0, count);
                                if (tempString == "m")
                                {
                                    count = resStream.Read(buf, 0, buf.Length);
                                    tempString = Encoding.ASCII.GetString(buf, 0, count);
                                    if (tempString == "a")
                                    {
                                        count = resStream.Read(buf, 0, buf.Length);
                                        tempString = Encoding.ASCII.GetString(buf, 0, count);
                                        if (tempString == "t")
                                        {
                                            count = resStream.Read(buf, 0, buf.Length);
                                            tempString = Encoding.ASCII.GetString(buf, 0, count);
                                            if (tempString == "e")
                                            {
                                                count = resStream.Read(buf, 0, buf.Length);
                                                tempString = Encoding.ASCII.GetString(buf, 0, count);
                                                if (tempString == ">")
                                                {
                                                    count = resStream.Read(buf, 0, buf.Length);
                                                    tempString = Encoding.ASCII.GetString(buf, 0, count);
                                                    if (tempString == "\n")
                                                    {
                                                        // consume the 26 characters before the Zestimate value
                                                        int consumeCt = 26;
                                                        while (consumeCt != 0)
                                                        {
                                                            count = resStream.Read(buf, 0, buf.Length);
                                                            tempString = Encoding.ASCII.GetString(buf, 0, count);
                                                            consumeCt--;
                                                        }
                                                        while (tempString != "<")
                                                        {
                                                            sb.Append(tempString);
                                                            count = resStream.Read(buf, 0, buf.Length);
                                                            tempString = Encoding.ASCII.GetString(buf, 0, count);
                                                        }
                                                        foundZestimate = true;
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
        return sb.ToString();
    }
}
